import discord
from discord.ext import tasks, commands
import aiohttp
import asyncio
import time
import platform
from datetime import datetime
from zoneinfo import ZoneInfo
import os
from dotenv import load_dotenv

# Charger les variables d'environnement (.env)
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")

CHANNEL_ID = 1411128142860517547  # ID du salon Discord (sans guillemets)

# Catégories et services surveillés
categories = {
    "Infrastructure": [
        {"name": "Hébergement Bot", "address": "https://panel.water-heberg.fr"},
    ],
    
    "<:emoji_6:1411167739732557845> • MatHeberg": [
        {"name": "Bot Gestion", "address": "51.75.118.18:20219"},
    ],
    
    "<:emoji_4:1411167669721235527> • Académie Velin": [
        {"name": "Bot Personnalisé", "address": ""},
        {"name": " Bot Statut", "address": ""},
    ],
        
    "<:emoji_4:1411167635529269320> • Skyloria": [
        {"name": "Bot Personnalisé", "address": ""},
    ]
}

# Icônes de statut
STATUS_ICONS = {
    "ok": "<a:emoji_1:1405929270148075700>",
    "slow": "<a:emoji_2:1405929303325282314>",
    "down": "<a:emoji_3:1405929330260836475>"
}

bot = commands.Bot(command_prefix="!", intents=discord.Intents.default())
message_to_edit = None

# Vérifie un site HTTP
async def check_http(url):
    timeout = aiohttp.ClientTimeout(total=5)
    headers = {"User-Agent": "Mozilla/5.0"}
    try:
        start = time.time()
        async with aiohttp.ClientSession(timeout=timeout, headers=headers) as session:
            async with session.get(url) as resp:
                if resp.status < 400:
                    return (time.time() - start) * 1000
        return None
    except:
        return None

# Vérifie un node TCP
async def check_tcp(host_port):
    start = time.time()
    try:
        host, port = host_port.split(":")
        port = int(port)
        reader, writer = await asyncio.wait_for(
            asyncio.open_connection(host, port),
            timeout=5
        )
        writer.close()
        await writer.wait_closed()
        return (time.time() - start) * 1000
    except:
        return None

# Détecte le type de test
async def get_status(address):
    if not address:  # Si l'adresse est vide
        return STATUS_ICONS["down"], "Non configuré"

    if address.startswith("http://") or address.startswith("https://"):
        latency = await check_http(address)

    elif ":" in address:  # IP ou domaine avec port
        latency = await check_tcp(address)

    else:  # IP ou domaine sans port → test port 80
        latency = await check_tcp(f"{address}:80")

    if latency is None:
        return STATUS_ICONS["down"], "Injoignable"
    elif latency > 1000:
        return STATUS_ICONS["slow"], f"{latency:.0f} ms"
    else:
        return STATUS_ICONS["ok"], f"{latency:.0f} ms"

# Construit l'embed Discord
async def build_status_embed():
    embed = discord.Embed(title="📡 Statut des services", color=0x2ECC71)

    for category, services in categories.items():
        lines = []
        for svc in services:
            emoji, latency_text = await get_status(svc["address"])
            lines.append(f"{emoji} • {svc['name']} : {latency_text}")
        embed.add_field(name=category, value="\n".join(lines), inline=False)

    legend = (
        f"{STATUS_ICONS['ok']} Joignable\n"
        f"{STATUS_ICONS['slow']} Ping > 1s\n"
        f"{STATUS_ICONS['down']} Injoignable"
    )

    embed.add_field(name="📖 •  Légende :", value=legend, inline=False)

    now = datetime.now(ZoneInfo("Europe/Paris")).strftime("%d/%m/%Y %H:%M")
    embed.set_footer(text=f"Dernière mise à jour : {now}")

    return embed

# Tâche automatique
@tasks.loop(minutes=1)
async def update_status():
    global message_to_edit
    channel = bot.get_channel(CHANNEL_ID)
    if channel is None:
        print(f"❌ Impossible de trouver le salon {CHANNEL_ID}")
        return

    embed = await build_status_embed()

    if message_to_edit is None:
        message_to_edit = await channel.send(embed=embed)
    else:
        await message_to_edit.edit(embed=embed)

# Commande manuelle
@bot.command()
async def status(ctx):
    global message_to_edit
    embed = await build_status_embed()
    if message_to_edit is None:
        message_to_edit = await ctx.send(embed=embed)
    else:
        await message_to_edit.edit(embed=embed)
        await ctx.send("✅ Statut mis à jour", delete_after=2)

# Démarrage
@bot.event
async def on_ready():
    print(f"✅ Bot connecté en tant que {bot.user}")
    await asyncio.sleep(2)
    update_status.start()

bot.run(TOKEN)